package threads;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Observable;

import data.Page;
import data.STATUS;



/**
 * Analyzes a page for URL's and Keywords.
 * @author Dan Dalton
 * @author Gavin Greene
 *
 * Takes a list of Keywords at construction, and counts the number of times those key
 * words appear in the document.
 *
 */
public class Analyser extends Observable implements Runnable, Comparable{
	
	/**
	 * Page to receive vigorous analysis.
	 */
	private Page my_page;
	/**
	 * User defined keywords to search the page's words for.
	 */
	private List<String> my_keywords;
	/**
	 * Resulting keywords and quantity pairs from the analysis.
	 */
	private Map<String, Integer> my_stats;
	/**
	 * Analyse the page using the provided keywords, and build a table of key/values.
	 * @param the_page to be analysed.
	 * @param the_keywords to look for and count.
	 */
	public Analyser(final Page the_page, final List<String> the_keywords){
		my_page = the_page;
		my_keywords = the_keywords;	
		my_stats = new HashMap<String, Integer>();
	}
	
	@Override
	public void run() {
		
		final long start = System.currentTimeMillis();
		
		// Add all the words to the Hashmap with an initial occurrence of zero.
		for (String word : my_keywords){
			my_stats.put(word, 0);
		}
		// For every word in my page...
		for (String word : my_page.getWords()){
			// If that word is in my stats (my keywords) then increment that words count.
			if(my_stats.keySet().contains(word)){
				int count = my_stats.get(word);
				count++;
				my_stats.put(word, count);
			}
		}
		
		final long end = System.currentTimeMillis();
		final long runtime = end - start;
		// Updating status with the stats (counts of occurences) and the runtime.
		my_page.setStatus(STATUS.ANALYSED, my_stats, runtime);
		finish();
	}
	/**
	 * Announce to the world: "Game over man..."
	 */
	private void finish(){
		this.setChanged();
		this.notifyObservers(my_page);
	}
	/**
	 * Gets my page.
	 * @return the page I'm working on.
	 */
	public Page getPage(){
		return my_page;
	}

	@Override
	public int compareTo(Object o) {
		//TODO: For some reason the TPE throws a fit if these aren't comparable?
		// This horrible workaround seems to have no negative effect... 
		return 1;
	}
}
